﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using YLPublicService.Extensions;
using System.Data.Common;
using System.Data;

using YLPublicService.TransferModel;

namespace YLPublicService
{
    public static class DataContextExtensions
    {
        public static List<T> ExecuteQuery<T>(this DataContext dataContext, IQueryable query)
        {
            DbCommand command = dataContext.GetCommand(query);
            dataContext.OpenConnection();

            using (DbDataReader reader = command.ExecuteReader())
            {
                return dataContext.Translate<T>(reader).ToList();
            }
        }

        private static void OpenConnection(this DataContext dataContext)
        {
            if (dataContext.Connection.State == ConnectionState.Closed)
            {
                dataContext.Connection.Open();
            }
        }
    }


    public partial class AdminService : ServiceBase<ServerUser>, IAdminService
    {

        public bool AddAdminUser(string loginName, string pwd, string memo, bool isAdmin, Guid guid)
        {
            if (!isOnline(guid))
                return false;
            //管理员的管理员帐户才能添加管理员
            if (getCurrentUser(guid).IsAdmin == false)
                return false;
            ServerUser admin = new ServerUser
            {
                LoginName = loginName,
                Enabled = true,
                PassWord = new Binary(HashAlgorithm.getHex(pwd)),
                Memo = memo,
                IsAdmin = isAdmin
            };

            try
            {
                ServerUser t;
                if (!TryFindUser(loginName, pwd, out t))
                {
                    dbContext.ServerUsers.InsertOnSubmit(admin);
                    dbContext.SubmitChanges();
                    return true;
                }
                return false;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 设置用户标识，以及创建文件夹。
        /// </summary>
        /// <param name="loginName"></param>
        /// <param name="guid"></param>
        /// <returns></returns>
        public bool EnableUser(string loginName, Guid guid)
        {
            if (!isOnline(guid))
                return false;
            var user = dbContext.Users.Where(u => u.LoginName == loginName).First();
            if (user != null)
            {
                user.Enabled = true;
                dbContext.SubmitChanges(ConflictMode.ContinueOnConflict);
                //添加用户帐目记录
                UserAccount account = new UserAccount { UserID = user.UserID, Money = 0m };
                dbContext.UserAccounts.InsertOnSubmit(account);
                dbContext.SubmitChanges();
                //!++ 创建用户文件夹
                settingManager.CreateUserOnDisk(loginName);
                return true;
            }
            return false;
        }
        /// <summary>
        /// 设置用户标识，但不会删除用户文件夹
        /// </summary>
        /// <param name="loginName"></param>
        /// <param name="guid"></param>
        /// <returns></returns>
        public bool DisableUser(string loginName, Guid guid)
        {
            if (isOnline(guid))
            {
                var user = dbContext.Users.Where(u => u.LoginName == loginName).First();
                if (user != null)
                {
                    user.Enabled = false;
                    dbContext.SubmitChanges();
                    return true;
                }
            }
            return false;
        }

        public IEnumerable<TransferModel.User> GetUsers(Guid guid)
        {
            if (isOnline(guid))
            {
                ServerUser serverUser = getCurrentUser(guid);

                var r = from relation in dbContext.ServerUserAndUsers
                        where relation.ServerUserID == serverUser.ServerUserID
                        select relation;
                var ret = from user in dbContext.Users
                          join relation in r on user.UserID equals relation.UserID
                          select TransferModel.User.Create(user.LoginName, user.Enabled);
                return ret;
            }
            else
                return null;
        }
        /// <summary>
        ///  //!+ 集合添加时是否需要事务控制
        /// </summary>
        /// <param name="serverUserLoginName"></param>
        /// <param name="guid"></param>
        /// <returns></returns>
        public bool ConbindAll(string serverUserLoginName, Guid guid)
        {
            var serverid = (from su in dbContext.ServerUsers
                            where su.LoginName == serverUserLoginName
                            select su.ServerUserID).First();

            var newItem = dbContext.Users.ToList().Select(
                u => new ServerUserAndUser { ServerUserID = serverid, UserID = u.UserID }
                );
            var oldItem = from r in dbContext.ServerUserAndUsers
                          where r.ServerUserID == serverid
                          select r;
            try
            {
                dbContext.ServerUserAndUsers.DeleteAllOnSubmit(oldItem);
                dbContext.ServerUserAndUsers.InsertAllOnSubmit(newItem);
                dbContext.SubmitChanges();
                return true;
            }
            catch
            {
                return false;
            }
        }

        public bool AddUser(string loginName, string pwd, string userName, string memo, Guid guid)
        {
            if (isOnline(guid))
            {
                User user = new User() { UserName = userName, Enabled = false, memo = memo, LoginName = loginName };
                user.PassWord = new Binary(HashAlgorithm.getHex(pwd));
                try
                {
                    //不得重复添加
                    if (dbContext.Users.Where(u => u.LoginName == loginName).Count() != 0)
                        return false;
                    dbContext.Users.InsertOnSubmit(user);
                    dbContext.SubmitChanges();
                    //!+ 添加ftp上的帐户
                    settingManager.AddUser(loginName, pwd);
                    return true;
                }
                catch (Exception)
                {
                    return false;
                }
            }
            return false;
        }
        /// <summary>
        /// 删除用户帐户，以及文件夹
        /// </summary>
        /// <param name="loginName"></param>
        /// <param name="guid"></param>
        /// <returns></returns>
        public bool DeleteUser(string loginName, Guid guid)
        {
            if (isOnline(guid))
            {
                try
                {
                    var user = dbContext.Users
                       .Where(u => u.LoginName == loginName).First();
                    dbContext.Users.DeleteOnSubmit(user);
                    dbContext.SubmitChanges();
                    //!+ delete ftp user 
                    settingManager.DeleteUser(loginName);
                    return true;
                }
                catch (Exception)
                {
                    return false;
                }
            }
            return false;
        }
  
        /// <summary>
        /// 尝试匹配一个ServerUser
        /// 信息不对以及没有启用都返回False
        /// </summary>
        /// <param name="loginName"></param>
        /// <param name="pwd"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        protected override bool TryFindUser(string loginName, string pwd, out ServerUser user)
        {
            var ret = from u in dbContext.ServerUsers
                      where u.LoginName == loginName && u.PassWord == new Binary(HashAlgorithm.getHex(pwd))
                      select u;

            if (ret.Count() > 0)
            {
                user = ret.First();
                return true;
            }
            else
            {
                user = null;
                return false;
            }
        }

    }
}
